package sqlanalysisgui.dialog;

import java.io.File;
import java.lang.reflect.InvocationTargetException;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.TouchEvent;
import org.eclipse.swt.events.TouchListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;

import sqlanalysisgui.view.ProjectListView;

import com.cho.core.RegCore;
import com.cho.core.db.OracleConnection;
import com.cho.core.db.dao.TableCreate;
import com.cho.core.db.dao.TableDao;
import com.cho.core.util.StringUtils;
import com.cho.core.vo.ProjectVo;

public class ProjectInfoDialog extends Dialog {
	private Text text_project_name;
	private Text text_source_path;
	private Button btnNewButton;
	private Text text_db_id;
	private Text text_db_pw;
	private Text text_db_host;
	private Text text_db_port;
	private Text text_db_SID;
	private Text text_include_file_extention;
	ProjectVo projectVo = new ProjectVo();
	
	/**
	 * Create the dialog.
	 * @param parentShell
	 */
	public ProjectInfoDialog(Shell parentShell) {
		super(parentShell);
	}

	/**
	 * Create contents of the dialog.
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite container = (Composite) super.createDialogArea(parent);
		container.setLayout(new GridLayout(1, false));
		final Shell shell = parent.getShell();
		Group grpSourceInfo = new Group(container, SWT.NONE);
		GridData gd_grpSourceInfo = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
		gd_grpSourceInfo.heightHint = 120;
		gd_grpSourceInfo.widthHint = 202;
		grpSourceInfo.setLayoutData(gd_grpSourceInfo);
		grpSourceInfo.setText("Source Info (필수)");
		
		Label lblF = new Label(grpSourceInfo, SWT.NONE);
		lblF.setBounds(10, 34, 72, 15);
		lblF.setText("프로젝트 명:");
		
		Label label = new Label(grpSourceInfo, SWT.NONE);
		label.setText("경          로:");
		label.setBounds(10, 70, 72, 15);
		
		text_project_name = new Text(grpSourceInfo, SWT.BORDER);
		text_project_name.setBounds(88, 31, 336, 21);
		
		text_source_path = new Text(grpSourceInfo, SWT.BORDER);
		text_source_path.setEditable(false);
		text_source_path.setBounds(88, 70, 254, 21);
		
		btnNewButton = new Button(grpSourceInfo, SWT.NONE);
		btnNewButton.setBounds(348, 68, 76, 25);
		btnNewButton.setText("폴더 찾기");
		
		Label label_1 = new Label(grpSourceInfo, SWT.NONE);
		label_1.setText("확장자 추가:");
		label_1.setBounds(10, 110, 72, 15);
		
		text_include_file_extention = new Text(grpSourceInfo, SWT.BORDER);
		text_include_file_extention.setToolTipText("추가 방법: java, jsp, php.. \r\n\r\n현재 등록되어 있는 확장자: jsp, asp, php, java, c, cc, cpp, cs, m, mm, vb, py");
		text_include_file_extention.setBounds(88, 107, 336, 21);
		
		
		Group grpF = new Group(container, SWT.NONE);
		GridData gd_grpF = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		gd_grpF.heightHint = 195;
		grpF.setLayoutData(gd_grpF);
		grpF.setText("DB Info (선택, 현재 오라클만 지원)");
		
		Label lblNewLabel = new Label(grpF, SWT.NONE);
		lblNewLabel.setBounds(10, 34, 56, 15);
		lblNewLabel.setText("I  D:");
		
		Label lblPW = new Label(grpF, SWT.NONE);
		lblPW.setText("P  W:");
		lblPW.setBounds(10, 69, 56, 15);
		
		Label lblHost = new Label(grpF, SWT.NONE);
		lblHost.setText("HOST:");
		lblHost.setBounds(10, 104, 56, 15);
		
		Label lblSid = new Label(grpF, SWT.NONE);
		lblSid.setText("SID:");
		lblSid.setBounds(10, 137, 56, 15);
		
		text_db_id = new Text(grpF, SWT.BORDER);
		text_db_id.setBounds(88, 34, 336, 21);
		
		text_db_pw = new Text(grpF, SWT.BORDER);
		text_db_pw.setBounds(88, 69, 336, 21);
		
		text_db_host = new Text(grpF, SWT.BORDER);
		text_db_host.setBounds(88, 104, 167, 21);
		
		Label lblPort = new Label(grpF, SWT.NONE);
		lblPort.setText("PORT:");
		lblPort.setBounds(262, 104, 33, 15);
		
		text_db_port = new Text(grpF, SWT.BORDER);
		text_db_port.setBounds(301, 104, 123, 21);
		text_db_port.setText("1521");
		
		text_db_SID = new Text(grpF, SWT.BORDER);
		text_db_SID.setBounds(88, 137, 167, 21);
		
		Button btnNewButton_1 = new Button(grpF, SWT.NONE);
		btnNewButton_1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				projectDataSetting();
				String dbConnectErrMsg = connectTest();
				if(dbConnectErrMsg.isEmpty()){
					MessageDialog.openInformation(shell, "Info", "DB 접속 성공!!");
				}else{
					MessageDialog.openError(shell, "Error", "DB 접속 에러" + dbConnectErrMsg);
				}
			}
		});
		btnNewButton_1.setBounds(348, 137, 76, 25);
		btnNewButton_1.setText("접속 테스트");

		hookButtonEvent(parent);
		
		return container;
	}
	
	private String connectTest(){
		//projectDataSetting();
		return OracleConnection.getConnectionTest(projectVo);
	}

	private void hookButtonEvent(final Composite parent){
		btnNewButton.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if(e.keyCode == 13){
					directoryDialogOpen(parent);
				}
			}
		});
		
		btnNewButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				directoryDialogOpen(parent);
			}
		});		
	}
	
	private void directoryDialogOpen(Composite parent){
		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();  
		ProjectListView view = (ProjectListView) page
				.findView(ProjectListView.ID);
		try{view.setDataRefresh();}catch(Exception e){}
		
		DirectoryDialog dialog = new DirectoryDialog(parent.getShell());
		String dir = dialog.open();
		
		if(dir != null){
			text_source_path.setText(dir);
		}
	}
	
	private void projectDataSetting(){
		projectVo.setProjectName(text_project_name.getText());
		projectVo.setProjectDirectory(text_source_path.getText());
		projectVo.setIncludeFileExtension(text_include_file_extention.getText());
		projectVo.setDbId(text_db_id.getText());
		projectVo.setDbPw(text_db_pw.getText());
		projectVo.setDbHost(text_db_host.getText());
		projectVo.setDbPort(text_db_port.getText());
		projectVo.setDbServiceName(text_db_SID.getText());
	}
	
	private void okButtonProcess(final Composite parent){
		projectDataSetting();
		
		if(validate(parent)){
			runProgressbar(parent);
			projectListRefresh();
			this.close();
		}
	}
	
	private void projectListRefresh(){
		IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
		ProjectListView view = (ProjectListView) page
				.findView(ProjectListView.ID);
		try{view.setDataRefresh();}catch(Exception e){}
	}
	
	private boolean validate(final Composite parent){
//		Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell() ;
		//Shell shell = this.getShell();
		Shell shell = parent.getShell();
		
		boolean validateOk = true;
		if(projectVo.getProjectName().isEmpty()){
			validateOk = false;
			MessageDialog.openError(shell, "Error", "프로젝트 명을 입력하세요.");
			text_project_name.setFocus();
		}else if(projectVo.getProjectDirectory().isEmpty()){
			validateOk = false;
			MessageDialog.openError(shell, "Error", "디렉토리를 선택하세요.");
			text_source_path.setFocus();
		}
		
		if(StringUtils.isNotEmpty(projectVo.getDbId())
				&& StringUtils.isNotEmpty(projectVo.getDbPw())
				&& StringUtils.isNotEmpty(projectVo.getDbHost())
				&& StringUtils.isNotEmpty(projectVo.getDbPort())
				&& StringUtils.isNotEmpty(projectVo.getDbServiceName())
				){
			
			String dbConnectErrMsg = connectTest();
			
			if(StringUtils.isNotEmpty(dbConnectErrMsg)){
				validateOk = false;
				MessageDialog.openError(shell, "Error", "DB 접속 에러" + dbConnectErrMsg);
				text_db_host.setFocus();
			}
		}
		
		return validateOk;
	}
	private void runProgressbar(final Composite parent){
		ProgressMonitorDialog dialog = new ProgressMonitorDialog(parent.getShell());    
		try {
			dialog.run(true, true, new IRunnableWithProgress() {
				public void run(IProgressMonitor monitor) {
					monitor.beginTask("소스를 분석 중입니다. ...", 150);
					runSourceAnalysis(monitor);
				}
			});
		} catch (InvocationTargetException | InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
	}
	private void runSourceAnalysis(IProgressMonitor monitor){
		monitor.subTask("소스를 분석을 시작합니다." );
		//Properties properties = new Properties();
		try {
			//TableCreate.dropTable();//초기화
			//TableCreate.runTableCreate();//초기화
			//properties.load(new FileInputStream("main.properties"));
			monitor.worked(1);//1
			//properties.list(System.out);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		try {
				monitor.subTask("소스 정보를 저장할 DB를 초기화하는 중입니다." );
				monitor.worked(5);//6
				TableCreate.runTableCreate();
				TableDao.deleteProjectInfo(projectVo.getProjectName());
				TableDao.deleteFileList(projectVo.getProjectName());
				TableDao.deleteTableList(projectVo.getProjectName());
				TableDao.deleteDbTalbeList(projectVo.getProjectName());
				
				TableDao.insertProjectInfo(projectVo);
				
				if(StringUtils.isEmpty(connectTest())){
					monitor.subTask("데이터베이스의 딕셔너리 정보를 저장하는 중입니다." );
					monitor.worked(10);//16
					TableDao.insertDbTableInfo(projectVo);
				}
				
				monitor.worked(20);//26
				RegCore c = new RegCore();
			
				monitor.subTask("지정한 경로의 소스를 분석하는 중입니다." );
				monitor.worked(54);//80
				c.readFolderForGUI(projectVo, new File(projectVo.getProjectDirectory()), monitor);
				monitor.subTask("소스 분석이 완료되었습니다." );
				monitor.worked(20);

			} catch (Exception e) {
				e.printStackTrace();
			}	
		monitor.worked(100);
		monitor.done();
	}
	/**
	 * Create contents of the button bar.
	 * @param parent
	 */
	@Override
	protected void createButtonsForButtonBar(final Composite parent) {
		Button button = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
				true);
		
		button.addTouchListener(new TouchListener() {
			@Override
			public void touch(TouchEvent e) {
				// CHO Auto-generated method stub
				okButtonProcess(parent);
			}
		});
		button.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				// CHO Auto-generated method stub
				okButtonProcess(parent);
			}
			@Override
			public void keyPressed(KeyEvent e) {
				//if(e.keyCode == 13){
					okButtonProcess(parent);
				//}
			}
		});
		button.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent e) {
				okButtonProcess(parent);
			}
		});
		createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
	}

	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(450, 411);
	}
}
